package com.wxmit.starter.file.core;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import com.wxmit.base.util.DateUtils;
import com.wxmit.base.util.StringUtils;
import com.wxmit.starter.file.FileApi;
import com.wxmit.starter.file.config.ShushanFileConfig;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;

/**
 * @author huangxiong
 * @date 2024/03/20 09:52
 * TODO::: 重写
 */
public class SystemFileApiImpl implements FileApi {


    @Override
    public Optional<String> validateFile(MultipartFile file) {
        if(Objects.isNull(file)){
            return Optional.of("文件不能为空");
        }
        StringBuilder sb = new StringBuilder();
        // 校验文件名
        String originalFilename = file.getOriginalFilename();
        if (StringUtils.isBlank(originalFilename) || originalFilename.length() > ShushanFileConfig.fileNameMaxLength) {
            sb.append("文件名不合法;");
        }
        // 校验文件大小
        if (file.getSize() > ShushanFileConfig.fileMaxSize) {
            sb.append("文件大小不能超过").append(ShushanFileConfig.fileMaxSize / 1024 / 1024).append("M;");
        }
        // 校验文件类型
        String ext = FileUtil.extName(originalFilename);
        if(!ShushanFileConfig.allowedExtension.contains(ext)){
            sb.append("当前文件后缀不合法;");
        }


        return Optional.ofNullable(sb.length() == 0 ? null : sb.toString());
    }

    @Override
    public String uploadFile(String module, MultipartFile file) throws IOException {
        Optional<String> validated = validateFile(file);
        if(validated.isPresent()){
            throw new IllegalArgumentException(validated.get());
        }
        module = Objects.isNull(module) ? "common" : module;
        String originalFilename = file.getOriginalFilename();
        String sysFileName = extractFilename(module,originalFilename);
        File sysFile = makeFile(sysFileName);
        file.transferTo(sysFile);
        return sysFileName;
    }


    @Override
    public byte[] downloadFile(String path) {
        return FileUtil.readBytes(ShushanFileConfig.buildFullFilePath(path));
    }

    @Override
    public boolean deleteFile(String path) {
        if(Objects.isNull(path) || path.length() == 0){
            throw new IllegalArgumentException("删除文件时，文件路径不能为空！");
        }
        return FileUtil.del(ShushanFileConfig.buildFullFilePath(path) );
    }

    /**
     *  构建文件
     * @param fileName  文件名
     * @return 文件
     */
    private  File makeFile(String fileName)
    {
        File desc = new File(ShushanFileConfig.buildFullFilePath(fileName));

        if (!desc.exists())
        {
            if (!desc.getParentFile().exists())
            {
                desc.getParentFile().mkdirs();
            }
        }
        return desc;
    }

    /**
     *  提取文件名
     * @param module 模块名
     * @param fileName 文件名
     * @return 新文件名
     */
    private  String extractFilename(String module,String fileName)
    {
        String extension = FileUtil.extName(fileName);
        if(Objects.isNull(module)){
            // yyyy/MM/dd/uuid.extension
            return StringUtils.format("{}{}{}.{} ",
                    DateUtils.datePath() ,ShushanFileConfig.separator,
                    IdUtil.getSnowflakeNextId() , extension);
        }else{
            // module/yyyy/MM/dd/uuid.extension
            return StringUtils.format("{}{}{}{}{}.{} ",
                    module ,ShushanFileConfig.separator,
                    DateUtils.datePath() ,ShushanFileConfig.separator,
                    IdUtil.getSnowflakeNextId() , extension);

        }
    }


    /**
     *  转换文件url前缀 和 文件路径
     * @param filePath 路径
     * @param reverse 是否反转 （true：  /filePath => /urlPrefix/filePath ，false：/urlPrefix/filePath => /filePath ）
     * @return 转换后的str
     */
    public String translateUrlPrefixAndFilePath(String filePath,boolean reverse){
        if(StringUtils.isEmpty(filePath)) return filePath;
        if(reverse){
            /**       /filePath => /urlPrefix/filePath          */
            return ShushanFileConfig.urlPrefix + ShushanFileConfig.separator + filePath;
        }else{
            /**       /urlPrefix/filePath => /filePath          */
            return StringUtils.startWith(filePath,ShushanFileConfig.urlPrefix) ?
                    filePath.replaceFirst(ShushanFileConfig.urlPrefix,"") : filePath;
        }
    }
}
